<template>
  <div class="app-container">
    <!-- 查询条件 开始 -->
    <el-form :inline="true" :model="queryObj" class="demo-form-inline">
      <el-form-item label="">
        <el-input v-model="queryObj.title" placeholder="课程标题" clearable size="medium"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-select v-model="queryObj.status" placeholder="发布状态">
          <el-option label="未发布" value="Draft"></el-option>
          <el-option label="已发布" value="Normal"></el-option>
        </el-select>
      </el-form-item>
      

      <el-form-item>
        <el-button type="success" icon="el-icon-search" size="small" @click="fetchData">搜索</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="warning" icon="el-icon-refresh-left" size="small" @click="resetData">重置</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-plus" size="small" @click="openAddDialog('发布新课程')">新增</el-button>
      </el-form-item>

      <el-button type="text" icon="el-icon-refresh" @click="refreshData" style="float: right;" title="刷新"></el-button>
    </el-form>
    <!-- 查询条件 结束 -->

    <!-- 数据表格 开始 -->
    <el-table
      v-loading="listLoading"
      :data="list"
      element-loading-text="Loading"
      border
      fit
      highlight-current-row>
      <el-table-column type="index" align="center" label="#"></el-table-column>
      <el-table-column label="课程名称">
        <template slot-scope="scope">
          {{ scope.row.title }}
        </template>
      </el-table-column>
      <el-table-column class-name="level-col" label="课程状态" width="100" align="center">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.status=='Draft'"
                  type="danger" size="medium">未发布</el-tag>
          <el-tag v-else-if="scope.row.status=='Normal'"
                  type="success" size="medium">已发布</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="课程价格" width="100" align="right">
        <template slot-scope="scope">
          <span>{{ scope.row.price > 0 ? scope.row.price.toFixed(2) : '免费' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="销售数量" width="100" align="right">
        <template slot-scope="scope">
          <span>{{ scope.row.buyCount }}</span>
        </template>
      </el-table-column>
      <el-table-column label="浏览数量" width="100" align="right">
        <template slot-scope="scope">
          {{ scope.row.viewCount }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="创建时间" width="180">
        <template slot-scope="scope">
          <i class="el-icon-time"/>
          <span>{{ scope.row.createTime }}</span>
        </template>
      </el-table-column>
      <el-table-column align="center" class-name="operation-col" label="操作" width="350">
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" @click="openUpdateCourseDialog(scope.row.id, '编辑课程')" size="mini">课程信息</el-button>
          <el-button type="primary" icon="el-icon-edit" @click="openTreeChapterDialog(scope.row.id, '编辑课程')" size="mini">课程大纲</el-button>
          <el-button type="danger" icon="el-icon-delete" @click="removeData(scope.row.id, scope.row.title)" size="mini">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 数据表格 结束 -->
    
    <!-- 分页条 开始 -->
    <el-pagination
      v-if="total>0"
      :current-page="pageNum"
      :page-sizes="[10, 20, 30, 40, 50, 100]"
      :page-size="pageSize"
      :total="total"
      style="padding: 30px 0; text-align: center;"
      layout="total, sizes, prev, pager, next, jumper"
      background
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange">
    </el-pagination>
    <!-- 分页条 结束 -->

    <!-- 添加或修改的模态框 开始 -->
    <el-dialog 
      id="addCourseDialog"
      :title="dialogTitle" 
      :visible.sync="dialogVisible" 
      :fullscreen="true"
      :append-to-body="true"
      :center="true">
      
      <!-- 步骤条 -->
      <el-steps :active="step" process-status="wait" align-center style="margin-bottom:40px;">
        <el-step title="填写课程基本信息"></el-step>
        <el-step title="创建课程大纲"></el-step>
        <el-step title="发布课程"></el-step>
      </el-steps>
      <br>
      <!-- 第一步，填写课程基本信息。开始 -->
      <el-form v-if="step==1" ref="courseObj" :model="courseObj" :rules="courseRules" :status-icon="true" size="medium" label-width="220px">
        <el-row>
          <el-col :span="18">
            <el-form-item label="课程标题" prop="title">
              <el-input v-model="courseObj.title" placeholder="示例：机器学习项目课：从基础到搭建" maxlength="50" clearable show-word-limit></el-input>
            </el-form-item>
            <el-row>
              <el-col :span="15">
                <el-form-item label="课程类别" prop="subjectId">
                  <el-select 
                    v-model="courseObj.subjectParentId" 
                    placeholder="一级分类" 
                    @change="changeOneSubject"
                    clearable>
                    <el-option 
                      v-for="(item,index) in oneSubjectList" 
                      :key="index"
                      :label="item.title" 
                      :value="item.id">
                    </el-option>
                  </el-select>
                  <el-select v-model="courseObj.subjectId" placeholder="二级分类" clearable >
                    <el-option 
                      v-for="(item,index) in twoSubjectList" 
                      :key="index"
                      :label="item.title" 
                      :value="item.id">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="9">
                <el-form-item label="课程讲师" prop="teacherId" label-width="80px">
                  <el-autocomplete
                    ref="teacherAutoComplete"
                    :fetch-suggestions="querySearchTeacher"
                    placeholder="点击选择课程讲师"
                    @select="handleSelectTeacher"
                    @change="changeTeacher"
                    prefix-icon="el-icon-search"
                    v-model="teacherName"
                    value-key="name"
                    :style="styleWidth">
                    <template slot-scope="{ item }">
                      <span style="float: left">
                        <el-avatar v-if="item.avatar" :size="28" :src="item.avatar" style="vertical-align: middle;font-size: 15px;"></el-avatar>
                        <el-avatar v-else :size="28" style="vertical-align: middle;font-size: 15px;">{{ item.name }}</el-avatar>
                        {{ item.name }}
                      </span>
                      <span style="float: right">
                        <el-tag v-if="item.level==1"
                          type="success" size="medium">高级讲师</el-tag>
                        <el-tag v-else-if="item.level==2"
                          type="danger" size="medium">首席讲师</el-tag>
                      </span>
                    </template>
                  </el-autocomplete>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="10">
                <el-form-item label="总课时数">
                  <el-input-number v-model="lessonNum" @change="changeCourseLessonNum" controls-position="right" :min="1" :style="styleWidth"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="课程价格" label-width="120px">
                  <el-input-number v-model="price" @change="changeCoursePrice" controls-position="right" :min="0"></el-input-number> 元
                </el-form-item>
              </el-col>
            </el-row>
          </el-col>
          <el-col :span="6" style="padding-left:40px;">
            <el-upload
              class="myimg-uploader"
              ref="courseCoverUpload"
              :action="BASE_API+'/oss/upload/course'"
              :show-file-list="false"
              :on-success="uploadCourseCoverSuccess"
              :before-upload="beforeCourseCoverUpload"
              :on-progress="uploadCourseCoverProgress"
              :limit="1"
              accept="image/jpeg"
              style="margin-bottom:10px;">
              <img v-if="uploadCourseCoverIcon=='el-icon-plus'&&cover" :src="cover" class="myimg">
              <i v-else :class="uploadCourseCoverIcon + ' myimg-uploader-icon'"></i>
            </el-upload>
            <span style="margin-left: 30px;">课程封面图</span>
          </el-col>
        </el-row>
        <el-form-item label="课程简介" prop="description">
          <tinymce v-model="courseObj.description" v-if="dialogVisible" :height="200" style="width:85%"></tinymce>
        </el-form-item>
      </el-form>
      <!-- 第一步，填写课程基本信息。结束 -->

      <!-- 第二步，创建课程大纲 开始-->
      <el-form v-else-if="step==2" :model="chapterObj" size="medium" label-width="80px">
        <!--<el-form-item label="章节名称" prop="title">
          <el-input v-model="chapterObj.title" placeholder="请输入课程标题" maxlength="50" show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="显示排序" prop="sort">
          <el-input-number v-model="courseObj.sort" controls-position="right" :min="0" :style="styleWidth"></el-input-number>
        </el-form-item>-->

        <el-button type="primary" @click="openAddChapterDialog">新增章节</el-button>
        
        <!-- 章节 -->
        <el-empty v-if="chapterTreeList.length==0" description="暂无数据" style="border: 1px solid #ddd;margin-top: 30px;"></el-empty>
        <ul v-else class="chapterList">
          <li
            v-for="chapter in chapterTreeList"
            :key="chapter.id">
            <p>
              {{chapter.title}}
              <span class="acts">
                <el-button type="text" @click="openAddVideoDialog(chapter.id)">添加课时</el-button>
                <el-button type="text" @click="openUpdateChapterDialog(chapter.id)">编辑</el-button>
                <el-button type="text" @click="removeChapterData(chapter.id, chapter.title)">删除</el-button>
              </span>
            </p>
            <!-- 视频 -->
            <ul v-if="chapter.children" class="chapterList videoList">
              <li 
                v-for="video in chapter.children"
                :key="video.id">
                <p>
                  {{video.title}}
                  <span class="acts">
                    <el-button type="text" @click="openUpdateVideoDialog(video.id)">编辑</el-button>
                    <el-button type="text" @click="removeVideoData(video.id, video.title)">删除</el-button>
                  </span>
                </p>
              </li>
            </ul>
          </li>
        </ul>
        

      </el-form>

      <!-- 第三步，发布课程。开始 -->
      <div v-else style="background-color: #e9f1fa;border: 8px dashed rgb(16 146 248);">
        <el-row>
          <el-col :span="10">
            <el-image :src="courseObj.cover" fit="fill" style="width: 100%;padding: 20px;height: 300px;"></el-image>
          </el-col>
          <el-col :span="14">
            <el-descriptions :title="courseObj.title" :column="1" :colon="false" class="coursePublishDescription">
              <el-descriptions-item label="" labelStyle="margin-right:0;">共 {{courseObj.lessonNum}} 课时</el-descriptions-item>
              <el-descriptions-item label="所属分类：">{{courseObj.subjectParentTitle}} - {{courseObj.subjectTitle}}</el-descriptions-item>
              <el-descriptions-item label="课程讲师：">{{courseObj.teacherName}}</el-descriptions-item>
              <el-descriptions-item v-if="courseObj.price>0" label="" labelStyle="margin-right:0;" contentStyle="font-size: 30px;color: #ee4d4d;">¥ {{courseObj.price.toFixed(2)}}</el-descriptions-item>
              <el-descriptions-item v-else label="" labelStyle="margin-right:0;" contentStyle="font-size: 30px;color: #67C23A;">免费</el-descriptions-item>
            
            </el-descriptions>
          </el-col>
        </el-row>
      </div>
      <!-- 第三步，发布课程。结束 -->

      <div slot="footer" class="dialog-footer">
        <el-button v-if="step>1" type="warning" @click="preStep(dialogTitle)">返回上一步修改</el-button>
        <el-button v-if="step<3" type="primary" @click="nextStep(dialogTitle)">{{step==1 ? '保存并继续下一步' : '下一步'}}</el-button>
        <el-button v-if="step==3" type="success" @click="publishCourse">确定发布</el-button>
      </div>
    </el-dialog>
    <!-- 添加或修改的模态框 结束 -->

    <!-- 添加或修改课程章节的模态框 开始 -->
    <el-dialog 
      :title="chapterDialogTitle" 
      :visible.sync="chapterDialogVisible" 
      :fullscreen="false"
      :append-to-body="true">
      <el-form ref="chapterObj" :model="chapterObj" :rules="chapterRules" :status-icon="true" size="medium" label-width="80px">
        <el-form-item label="章节名称" prop="title">
          <el-input v-model="chapterObj.title" placeholder="示例：第一章：学习介绍" maxlength="50" show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="显示排序">
          <el-input-number v-model="chapterObj.sort" controls-position="right" :min="0" ></el-input-number>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="chapterDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveOrUpdateChapter('chapterObj')">保 存</el-button>
      </div>
    </el-dialog>
    <!-- 添加或修改课程章节的模态框 结束 -->

    <!-- 添加或修改课程视频的模态框 开始 -->
    <el-dialog 
      :title="videoDialogTitle" 
      :visible.sync="videoDialogVisible" 
      :fullscreen="false"
      :append-to-body="true"
      :before-close="beforeVideoDialogClose">
      <el-form ref="videoObj" :model="videoObj" :rules="videoRules" :status-icon="true" size="medium" label-width="80px">
        <el-form-item label="课时标题" prop="title">
          <el-input v-model="videoObj.title" placeholder="示例：第一节：基础知识讲解" maxlength="50" show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="显示排序">
          <el-input-number v-model="videoObj.sort" controls-position="right" :min="0" ></el-input-number>
        </el-form-item>
        <el-form-item label="是否免费">
          <el-radio-group v-model="videoObj.free">
            <el-radio :label="true">免费</el-radio>
            <el-radio :label="false">默认</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="上传视频">
          <el-upload 
            :action="BASE_API+'/vod/upload'"
            :on-success="uploadVodSuccess"
            :on-remove="uploadVodRemove"
            :before-remove="beforeVodRemove"
            :on-exceed="uploadVodExceed"
            :file-list="videoFileList"
            :limit="1"
            class="upload-demo">
            <el-button type="warning" size="small">上传视频</el-button>
            <el-tooltip placement="right-end" effect="light">
              <div slot="content">
                最大支持1G，<br>
                支持3GP、ASF、AVI、DAT、DV、FLV、F4V、<br>
                GIF、M2T、M4V、MJ2、MJPEG、MKV、MOV、MP4、<br>
                MPE、MPG、MPEG、MTS、OGG、QT、RM、RMVB、<br>
                SWF、TS、VOB、WMV、WEBM 等视频格式上传
              </div>
              <i class="el-icon-question"></i>
            </el-tooltip>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="videoDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveOrUpdateVideo('videoObj')">保 存</el-button>
      </div>
    </el-dialog>
    <!-- 添加或修改课程视频的模态框 结束 -->

  </div>
</template>
<script>
import Tinymce from '@/components/Tinymce'             // 导入富文本编辑器组件
import courseApi from '@/api/edu/course'               // 导入课程API接口
import chapterApi from '@/api/edu/chapter'             // 导入课程章节API接口
import videoApi from '@/api/edu/video'                 // 导入课程视频API接口
import {getAllTeacher} from '@/api/edu/teacher'        // 导入讲师API接口中的方法
import {getOneSubject,getTwoSubject} from '@/api/edu/subject' // 导入课程分类API接口中的方法

export default {
  components: {                       // 定义多个局部组件
    Tinymce
  },
  data() {                            // 定义页面中显示的模型数据
    // 自定义验证，验证课程讲师
    var validateTeacherId = (rule, value, callback) => {
      if (!this.courseObj.teacherId || this.courseObj.teacherId === '') {
        callback(new Error('请选择课程讲师'));
      } else {
        callback();
      }
    };
    return {
      pageNum: 1,                     // 当前页
      pageSize: 10,                   // 每页显示条数
      queryObj: {},                   // 查询条件
      list: null,                     // 数据列表
      total: null,                    // 总记录数         
      listLoading: true,              // 是否正在加载
      dialogTitle: '',                // 模态框标题
      dialogVisible: false,           // 模态框是否可见
      styleWidth:'width: 100%;',      // 宽度的样式
      step: 1,                        // 当前激活步骤
      BASE_API:process.env.BASE_API,  // 获取dev.env.js里面地址
      teacherList:[],                 // 所有讲师数据列表
      teacherName:'',                 // 自动搜索教师姓名
      oneSubjectList:[],              // 课程一级分类列表
      twoSubjectList:[],              // 课程二级分类列表
      courseObj: {                    // 课程基本信息数据
        id:null,                      // --课程ID
        title: '',                    // --课程标题
        subjectId: '',                // --课程类别ID
        subjectParentId: '',          // --课程类别父级ID
        teacherId: '',                // --课程讲师ID
        lessonNum:1,                  // --总课时
        cover:null,                   // --课程封面图片路径
        price: 0,                     // --课程销售价格
        description: 0,               // --课程简介
      },
      lessonNum:1,                    // --总课时，计数器
      price: 0,                       // --课程销售价格，计数器
      cover:null,                     // --课程封面图片路径，上传组件
      uploadCourseCoverIcon:'el-icon-plus',// 课程封面图上传图标
      chapterTreeList:[],             // 课程章节树形结构数据列表
      chapterDialogTitle: '',         // 课程章节模态框标题
      chapterDialogVisible:false,     // 课程章节模态框是否可见
      chapterObj: {                   // 章节数据
        title: '',                    // --章节名称
        sort:0,                       // --章节排序
        courseId:null                 // --课程ID
      },      
      videoDialogTitle: '',           // 课程视频模态框标题
      videoDialogVisible:false,       // 课程视频模态框是否可见
      videoFileList:[],               // 上传的视频文件列表
      videoObj: {                     // 视频数据
        title: '',                    // --视频标题
        sort:0,                       // --视频排序
        free:false,                   // --是否可用试听
        courseId:null,                // --课程ID
        chapterId:null                // --章节ID
      },      
      courseRules: {                  // 课程表单验证
        title: [
          { required: true, message: '请输入课程标题', trigger: 'blur' },
          { max: 50, message: '最多可输入 50 个字符', trigger: 'blur' }
        ],
        subjectId: [
          { required: true, message: '请选择课程分类', trigger: 'blur' }
        ],
        teacherId: [
          //{ required: true, message: '请选择课程讲师', trigger: 'change' }
          {validator: validateTeacherId, trigger: 'change'}
        ]
      },
      chapterRules: {                  // 章节表单验证
        title: [
          { required: true, message: '请输入章节名称', trigger: 'blur' },
          { max: 50, message: '最多可输入 50 个字符', trigger: 'blur' }
        ]
      },
      videoRules: {                  // 视频表单验证
        title: [
          { required: true, message: '请输入课时标题', trigger: 'blur' },
          { max: 50, message: '最多可输入 50 个字符', trigger: 'blur' }
        ]
      },
      avatarUrl:"images/avatar.png",  // 默认显示头像
      
    }
  },
  created() {               // 在页面渲染之前执行"
    // 调用抓取数据的方法
    this.fetchData()        
  },                        
  methods: {                // 定义多个方法
    
    /**
     * 抓取数据的方法
     */
    fetchData() {
      this.listLoading = true
      courseApi.page(this.pageNum, this.pageSize, this.queryObj).then(response => {
          this.list = response.data.records
          this.total = response.data.total
          this.listLoading = false
        })
    },

    /**
     * 更换当前页
     * @param {number} pageNum 当前页
     */
    handleCurrentChange(pageNum) {
      this.pageNum = pageNum
      this.fetchData()
    },
    
    /**
     * 更换每页显示条数
     * @param {number} pageSize 每页显示条数
     */
    handleSizeChange(pageSize) {
      this.pageSize = pageSize
      this.fetchData()
    },

    /**
     * 重置查询条件
     */
    resetData() {
      // 清空查询条件
      this.queryObj = {}
      // 重新获取数据
      this.fetchData()
    },
    
    /**
     * 刷新数据
     */
    refreshData() {
      this.listLoading = true
      setTimeout(() => this.fetchData() ,"200");
    },

    /**
     * 打开添加模态框
     * @param {string} dialogTitle 模态框标题
     */
    openAddDialog(dialogTitle) {
      // 清空保存数据
      this.courseObj = {}
      // 默认课程讲师
      this.teacherName = ''
      // 默认总课时数
      this.courseObj.lessonNum = this.lessonNum = 1
      // 默认销售价格
      this.courseObj.price = this.price = 0
      // 默认封面图
      this.cover = null
      // 默认课程封面图上传图标
      this.uploadCourseCoverIcon = 'el-icon-plus'
      // 默认第一步
      this.step = 1
      // 加载所有讲师数据列表
      this.loadAllTeacher()
      // 加载课程一级分类列表
      this.loadOneSubject()
      // 重置表单验证
      if(this.$refs['courseObj']) {
        this.$refs['courseObj'].resetFields();
      }
      // 设置模态框标题
      this.dialogTitle = dialogTitle
      // 显示模态框
      this.dialogVisible = true
    },

    /**
     * 打开修改课程基本信息模态框
     * @param {string} id 课程ID
     * @param {string} dialogTitle 模态框标题
     */
    openUpdateCourseDialog(id, dialogTitle) {
      // 当前为第一步
      this.step = 1
      // 清空保存数据
      this.courseObj = {}
      // 默认课程封面图上传图标
      this.uploadCourseCoverIcon = 'el-icon-plus'
      // 加载所有讲师数据列表
      this.loadAllTeacher()
      // 加载课程一级分类列表
      this.loadOneSubject()
      // 根据ID获取数据
      this.getById(id)
      // 重置表单验证
      if(this.$refs['courseObj']) {
        this.$refs['courseObj'].resetFields();
      }
      // 设置模态框标题
      this.dialogTitle = dialogTitle
      // 显示模态框
      this.dialogVisible = true
    },

    /**
     * 打开修改课程大纲模态框
     * @param {string} id 课程ID
     * @param {string} dialogTitle 模态框标题
     */
    openTreeChapterDialog(id, dialogTitle) {
      // 当前为第二步
      this.step = 2
      // 清空保存数据
      this.courseObj = {}
      this.courseObj.id = id
      // 加载课程章节树形结构数据列表
      this.loadChapterTree(id)
      // 设置模态框标题
      this.dialogTitle = dialogTitle
      // 显示模态框
      this.dialogVisible = true
    },

    /**
     * 打开确认发布课程模态框
     * @param {string} id 课程ID
     * @param {string} dialogTitle 模态框标题
     */
    openConfirmCourseDialog(id, dialogTitle) {
      // 当前为第三步
      this.step = 3
      // 清空保存数据
      this.courseObj = {}
      this.courseObj.cover = ""
      // 默认课程封面图上传图标
      this.uploadCourseCoverIcon = 'el-icon-plus'
      // 加载所有讲师数据列表
      this.loadAllTeacher()
      // 加载课程一级分类列表
      this.loadOneSubject()
      // 根据ID获取数据
      this.getById(id)
      // 设置模态框标题
      this.dialogTitle = dialogTitle
      // 显示模态框
      this.dialogVisible = true

    },

    /**
     * 根据ID获取数据
     * @param {string} id 课程ID
     */
    getById(id) {
      courseApi.getById(id).then(response => {
        this.courseObj = response.data.courseInfo
        this.lessonNum = this.courseObj.lessonNum
        this.price = this.courseObj.price
        this.cover = this.courseObj.cover
        this.loadTwoSubject(this.courseObj.subjectParentId)
        this.teacherName = this.courseObj.teacherName
      }).catch(error => {
        console.error(error)
      })
    },

    /**
     * 删除数据
     * @param {string} id   主键
     * @param {string} name 名称
     */
    removeData(id, name) {
      // 确认信息
      this.$confirm(`此操作将永久删除该课程【${name}】, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {   // 点击确定后执行的方法
        courseApi.remove(id).then(response => {
          // 提示信息
          this.$message.success('删除成功!');
          // 刷新数据
          this.refreshData()
        }).catch(error => {
          console.error(error)
        })
      }).catch(() => {  // 点击取消后执行的方法
                
      });
    },

    /**
     * 打开添加章节模态框
     */
    openAddChapterDialog() {
      this.chapterObj = {}
      this.chapterObj.sort = 0
      this.chapterObj.courseId = this.courseObj.id
      // 重置表单验证
      if(this.$refs['chapterObj']) {
        this.$refs['chapterObj'].resetFields();
      }
      this.chapterDialogTitle = '新增章节'
      this.chapterDialogVisible = true
    },

    /**
     * 打开修改章节模态框
     * @param {string} chapterId
     */
    openUpdateChapterDialog(chapterId) {
      this.chapterObj = {}
      this.getChapterById(chapterId)
      // 重置表单验证
      if(this.$refs['chapterObj']) {
        this.$refs['chapterObj'].resetFields();
      }
      this.chapterDialogTitle = '编辑章节'
      this.chapterDialogVisible = true
    },

    /**
     * 添加或修改章节的保存
     */
    saveOrUpdateChapter(formName) {
      // 表单验证
      this.$refs[formName].validate((valid) => {
        // 验证成功
        if (valid) {
          const loading = this.$loading({
            lock: true,
            text: '保存中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.5)'
          });
          // 如果没有ID
          if(!this.chapterObj.id) {
            // 添加章节
            this.addChapter(loading)
          }
          // 如果有ID
          else {
            // 修改章节
            this.updateChapter(loading)
          }
        } 
        // 验证失败
        else {
          console.log('error submit!!');
          return false;
        }
      });
    },

    /**
     * 打开添加课时模态框
     * @param {string} chapterId 章节ID
     */
    openAddVideoDialog(chapterId) {
      this.videoObj = {}
      this.videoObj.sort = 0
      this.videoObj.free = false
      this.videoObj.chapterId = chapterId
      this.videoObj.courseId = this.courseObj.id
      this.videoFileList = []
      // 重置表单验证
      if(this.$refs['videoObj']) {
        this.$refs['videoObj'].resetFields();
      }
      this.videoDialogTitle = '新增课时'
      this.videoDialogVisible = true
    },

    /**
     * 打开修改课时模态框
     * @param {string} videoId 视频ID
     */
    openUpdateVideoDialog(videoId) {
      this.videoObj = {}
      this.videoFileList = []
      this.getVideoById(videoId)
      // 重置表单验证
      if(this.$refs['videoObj']) {
        this.$refs['videoObj'].resetFields();
      }
      this.videoDialogTitle = '编辑课时'
      this.videoDialogVisible = true
    },

    /**
     * 在课程视频的模态框关闭之前执行
     */
    beforeVideoDialogClose(done) {
      // 如果是修改课程视频模态框并且修改了视频资源文件，阻止关闭模态框
      if (this.videoObj.id && this.videoObj.oldVideoSourceId != this.videoObj.videoSourceId) {
        this.$alert('视频资源文件已修改，请务必点击保存！', '警告', {type:'warning'})
        // 阻止关闭
        return done(false)
      }
      // 允许关闭
      return done(true)
    },

    /**
     * 添加或修改课时的保存
     */
    saveOrUpdateVideo(formName) {
      // 表单验证
      this.$refs[formName].validate((valid) => {
        // 验证成功
        if (valid) {
          const loading = this.$loading({
            lock: true,
            text: '保存中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.5)'
          });
          // 如果没有ID
          if(!this.videoObj.id) {
            // 添加课时
            this.addVideo(loading)
          }
          // 如果有ID
          else {
            // 修改课时
            this.updateVideo(loading)
          }
        } 
        // 验证失败
        else {
          console.log('error submit!!');
          return false;
        }
      });
    },

    

    /**
     * 上一步
     * @param {string} dialogTitle 模态框标题
     */
    preStep(dialogTitle) {
      // 当前为第二步
      if (this.step == 2) {
        this.openUpdateCourseDialog(this.courseObj.id, dialogTitle)
      }
      // 当前为第三步
      else if (this.step == 3) {
        this.openTreeChapterDialog(this.courseObj.id, dialogTitle)
      }
    },

    /**
     * 下一步
     * @param {string} dialogTitle 模态框标题
     */
    nextStep(dialogTitle) {
      // 第一步，保存课程基本信息
      if (this.step == 1) {
        // 表单验证
        this.$refs['courseObj'].validate((valid) => {
          // 验证成功
          if (valid) {
            const loading = this.$loading({
              lock: true,
              text: '保存课程基本信息...',
              spinner: 'el-icon-loading',
              background: 'rgba(0, 0, 0, 0.5)'
            });
            // 如果没有ID
            if (!this.courseObj.id) {
              // 添加课程基本信息
              this.addCourse(loading, dialogTitle);
            }
            // 如果有ID
            else {
              // 修改课程基本信息
              this.updateCourse(loading, dialogTitle);
            }
          }
        });
      }
      // 第二步，保存课程章节
      else if (this.step == 2) {
        // 跳转到第三步，确认发布课程
        this.openConfirmCourseDialog(this.courseObj.id, dialogTitle)
      }
    },

    /**
     * 添加课程基本信息
     * @param {obj} loading 加载组件
     * @param {string} dialogTitle 模态框标题
     */
    addCourse(loading, dialogTitle) {
      courseApi.add(this.courseObj).then(response => {
        loading.close();
        // 提示信息
        this.$message.success('添加课程基本信息成功!');
        // 跳转到下一步，编辑课程大纲
        this.openTreeChapterDialog(response.data.courseId, dialogTitle)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 修改课程基本信息
     * @param {obj} loading 加载组件
     * @param {string} dialogTitle 模态框标题
     */
    updateCourse(loading, dialogTitle) {
      courseApi.update(this.courseObj).then(response => {
        loading.close();
        // 提示信息
        this.$message.success('修改课程基本信息成功!');
        // 跳转到下一步，编辑课程大纲
        this.openTreeChapterDialog(this.courseObj.id, dialogTitle)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 发布课程
     */
    publishCourse() {
      const loading = this.$loading({
        lock: true,
        text: '发布课程...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.5)'
      });
      courseApi.publish(this.courseObj.id).then(response => {
        loading.close();
        this.dialogVisible = false
        // 提示信息
        this.$message.success('课程发布成功!');
        // 回到第一页
        this.pageNum = 1;
        // 清空查询条件
        this.resetData()
      })
    },

    /**
     * 添加章节
     */
    addChapter(loading) {
      chapterApi.add(this.chapterObj).then(response => {
        loading.close();
        this.chapterDialogVisible = false
        // 提示信息
        this.$message.success('添加章节成功!');
        // 重新加载课程章节树形结构数据列表
        this.loadChapterTree(this.courseObj.id)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 修改章节
     */
    updateChapter(loading) {
      chapterApi.update(this.chapterObj).then(response => {
        loading.close();
        this.chapterDialogVisible = false
        // 提示信息
        this.$message.success('修改章节成功!');
        // 重新加载课程章节树形结构数据列表
        this.loadChapterTree(this.courseObj.id)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 根据ID获取章节数据
     * @param {string} chapterId 章节ID
     */
    getChapterById(chapterId) {
      chapterApi.getById(chapterId).then(response => {
        this.chapterObj = response.data.chapter
      }).catch(error => {
        console.error(error)
      })
    },

    /**
     * 删除章节数据
     * @param {string} chapterId 章节ID
     * @param {string} chapterName 章节名称
     */
    removeChapterData(chapterId, chapterName) {
      // 确认信息
      this.$confirm(`此操作将永久删除该章节【${chapterName}】, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {   // 点击确定后执行的方法
        chapterApi.remove(chapterId).then(response => {
          // 提示信息
          this.$message.success('删除成功!');
          // 重新加载课程章节树形结构数据列表
          this.loadChapterTree(this.courseObj.id)
        }).catch(error => {
          console.error(error)
        })
      }).catch(() => {  // 点击取消后执行的方法
                
      });
    },

    /**
     * 添加课时
     */
    addVideo(loading) {
      videoApi.add(this.videoObj).then(response => {
        loading.close();
        this.videoDialogVisible = false
        // 提示信息
        this.$message.success('添加课时成功!');
        // 重新加载课程章节树形结构数据列表
        this.loadChapterTree(this.courseObj.id)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 修改课时
     */
    updateVideo(loading) {
      videoApi.update(this.videoObj).then(response => {
        loading.close();
        this.videoDialogVisible = false
        // 提示信息
        this.$message.success('修改课时成功!');
        // 重新加载课程章节树形结构数据列表
        this.loadChapterTree(this.courseObj.id)
      }).catch(error => {
        console.error(error)
        loading.close();
      })
    },

    /**
     * 根据ID获取课时数据
     * @param {string} videoId 视频ID
     */
    getVideoById(videoId) {
      videoApi.getById(videoId).then(response => {
        this.videoObj = response.data.video
        if (this.videoObj.videoSourceId) {
          this.videoFileList = [{name: this.videoObj.videoOriginalName, url: ''}]
          this.videoObj.oldVideoSourceId = this.videoObj.videoSourceId
        }
      }).catch(error => {
        console.error(error)
      })
    },

    /**
     * 删除课时数据
     * @param {string} videoId 视频ID
     * @param {string} videoName 课时标题
     */
    removeVideoData(videoId, videoName) {
      // 确认信息
      this.$confirm(`此操作将永久删除该课时【${videoName}】, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {   // 点击确定后执行的方法
        videoApi.remove(videoId).then(response => {
          // 提示信息
          this.$message.success('删除成功!');
          // 重新加载课程章节树形结构数据列表
          this.loadChapterTree(this.courseObj.id)
        }).catch(error => {
          console.error(error)
        })
      }).catch(() => {  // 点击取消后执行的方法
                
      });
    },

    /**
     * 更换课程讲师
     */
    changeTeacher() {
      // 移除课程对象中的讲师ID属性
      this.$delete(this.courseObj, 'teacherId')
      // 表单验证
      this.$refs['courseObj'].validateField('teacherId')
    },

    /**
     * 自动搜索讲师
     */
    querySearchTeacher(queryString, cb) {
      var restaurants = this.teacherList;
      var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },

    /**
     * 创建字符串过滤器
     */
    createFilter(queryString) {
      return (restaurant) => {
        return (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
      };
    },

    /**
     * 选择讲师
     */
    handleSelectTeacher(item) {
      this.courseObj.teacherId = item.id
    },

    /**
     * 更换课程一级分类
     */
    changeOneSubject(parentId) {
      // 清空二级分类的值
      this.$delete(this.courseObj, "subjectId")
      // 加载课程二级分类列表
      this.loadTwoSubject(parentId)
    },

    /**
     * 上传课程封面图之前
     */
    beforeCourseCoverUpload(file) {
      const isJPG = file.type === 'image/jpeg';
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error('上传课程封面图片只能是 JPG 格式!');
      }
      if (!isLt2M) {
        this.$message.error('上传课程封面图片大小不能超过 2MB!');
      }
      return isJPG && isLt2M;
    },

    /**
     * 上传课程封面图进度中
     */
    uploadCourseCoverProgress() {
      this.uploadCourseCoverIcon = "el-icon-loading"
    },

    /**
     * 上传课程封面图成功
     */
    uploadCourseCoverSuccess(response, file) {
      this.cover = response.data.url
      this.courseObj.cover = this.cover
      this.uploadCourseCoverIcon = "el-icon-plus"
      this.$refs['courseCoverUpload'].clearFiles()
    },

    /**
     * 更换课程课时数
     */
    changeCourseLessonNum() {
      this.courseObj.lessonNum = this.lessonNum
    },

    /**
     * 更换课程价格
     */
    changeCoursePrice() {
      this.courseObj.price = this.price
    },

    /**
     * 上传视频文件成功
     */
    uploadVodSuccess(response, file, fileList) {
      // 获取云端视频资源ID
      this.videoObj.videoSourceId = response.data.videoId
      // 获取视频名称并赋值
      this.videoObj.videoOriginalName = file.name
    },

    /**
     * 删除视频文件
     */
    uploadVodRemove(file, fileList) {
      videoApi.removeVideoSource(this.videoObj.videoSourceId).then(response => {
        this.$message.success('删除视频资源成功！')
        this.$delete(this.videoObj, 'videoSourceId')
        this.$delete(this.videoObj, 'videoOriginalName')
        this.videoFileList = []
      })
    },

    /**
     * 删除视频文件之前
     */
    beforeVodRemove(file, fileList) {
      // 确认信息
      return this.$confirm(`确定移除 ${ file.name }？`, '提示', {type: 'warning'});
    },

    /**
     * 上传视频文件超出个数限制时
     */
    uploadVodExceed() {
      this.$message.warning('想要重新上传视频，请先删除已上传的视频！')
    },

    /**
     * 加载所有讲师数据列表
     */
    loadAllTeacher() {
      getAllTeacher().then(response => {
        this.teacherList = response.data.items
      })
    },

    /**
     * 加载所有课程一级分类列表
     */
    loadOneSubject() {
      getOneSubject().then(response => {
        this.oneSubjectList = response.data.list
      })
    },

    /**
     * 加载课程二级分类
     * @param {string} oneSubjectId 课程一级分类ID
     */
    loadTwoSubject(oneSubjectId) {
      getTwoSubject(oneSubjectId).then(response => {
        this.twoSubjectList = response.data.list
      })
    },

    /**
     * 加载课程章节树形结构列表
     * @param {string} courseId 课程ID
     */
    loadChapterTree(courseId) {
      chapterApi.tree(courseId).then(response => {
        this.chapterTreeList = response.data.tree
      })
    },
   

  }
}
</script>
<style>
.myimg-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.myimg-uploader .el-upload:hover {
  border-color: #409EFF;
}
.myimg-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 128px;
  height: 128px;
  line-height: 128px;
  text-align: center;
}
.myimg {
  width: 128px;
  height: 128px;
  display: block;
}
</style>
<style scoped>
.tinymce-container {
  line-height: 29px;
}
.chapterList {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
}
.chapterList li {
  position: relative;
}
.chapterList p {
  float: left;
  font-size: 18px;
  margin: 10px 0;
  padding: 10px;
  height: 50px;
  line-height: 30px;
  width: 100%;
  border: 1px solid rgb(29, 175, 243);
}
.chapterList .acts {
    float: right;
}
.chapterList .videoList {
  margin-left: 100px;
}
</style>
<style>
#addCourseDialog .el-dialog{
  background-color: #303133;
}
#addCourseDialog .el-dialog__title {
  color: #fff;
  font-size: 25px;
  font-weight: bold;
}
#addCourseDialog .chapterList p {
  border: 1px solid rgb(29, 175, 243);
  color: #fff;
}
#addCourseDialog .el-form-item__label {
  color: #ececec;
}
#addCourseDialog .el-input__inner {
  background-color: #fff0;
  border: 1px solid #3a75ff;
  color: #b4b8c1;
}
#addCourseDialog .el-input .el-input__count .el-input__count-inner {
  background-color: rgba(255, 255, 255, 0);
}
#addCourseDialog .el-input-number.is-controls-right .el-input-number__decrease {
  border-left: 1px solid #8f94a0;
}
#addCourseDialog .el-input-number__decrease, .el-input-number__increase {
  background: #f5f7fa00;
  color: #b5b9c1;
}
#addCourseDialog .el-input-number.is-controls-right .el-input-number__increase {
  border-bottom: 1px solid #898c94;
}
#addCourseDialog .el-input-number__increase {
  border-left: 1px solid #8f94a0;
}
#addCourseDialog .el-input-number__decrease, .el-input-number__increase {
  color: #b5b9c1;
}
#addCourseDialog .el-form-item.is-error .el-input__inner, 
#addCourseDialog .el-form-item.is-error .el-input__inner:focus, 
#addCourseDialog .el-form-item.is-error .el-textarea__inner, 
#addCourseDialog .el-form-item.is-error .el-textarea__inner:focus, 
#addCourseDialog .el-message-box__input input.invalid, 
#addCourseDialog .el-message-box__input input.invalid:focus {
  border-color: #F56C6C;
}
#addCourseDialog .mce-panel {
  border: 0 solid #3e8acf;
}
#addCourseDialog .mce-container, .mce-container *, .mce-widget, .mce-widget *, .mce-reset {
  background: #2591de00;
}
#addCourseDialog .mce-menubar {
  border: 1px solid #3e8acf;
}
#addCourseDialog .mce-menubar .mce-menubtn button span {
  color: #e6e6e6;
}
#addCourseDialog .mce-btn {
  background: #ffffff00;
}
#addCourseDialog .mce-ico {
  color: #919191;
}
.coursePublishDescription {
  font-size: 16px;
  padding: 20px;
  margin-top: 20px;
}
.coursePublishDescription .el-descriptions__title {
  font-size: 30px;
}
.coursePublishDescription .el-descriptions__body {
  background-color: #fff0;
}
</style>